home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / srcuc.zip / BCHGCC.H < prev    next >
C/C++ Source or Header  |  1992-06-04  |  13KB  |  434 lines

  1. /* -*-C-*-
  2.  
  3. $Header: /scheme/src/microcode/RCS/bchgcc.h,v 9.50 1992/06/04 14:42:38 jinx Exp $
  4.  
  5. Copyright (c) 1987-1992 Massachusetts Institute of Technology
  6.  
  7. This material was developed by the Scheme project at the Massachusetts
  8. Institute of Technology, Department of Electrical Engineering and
  9. Computer Science.  Permission to copy this software, to redistribute
  10. it, and to use it for any purpose is granted, subject to the following
  11. restrictions and understandings.
  12.  
  13. 1. Any copy made of this software must include this copyright notice
  14. in full.
  15.  
  16. 2. Users of this software agree to make their best efforts (a) to
  17. return to the MIT Scheme project any improvements or extensions that
  18. they make, so that these may be included in future releases; and (b)
  19. to inform MIT of noteworthy uses of this software.
  20.  
  21. 3. All materials developed as a consequence of the use of this
  22. software shall duly acknowledge such use, in accordance with the usual
  23. standards of acknowledging credit in academic research.
  24.  
  25. 4. MIT has made no warrantee or representation that the operation of
  26. this software will be error-free, and MIT is under no obligation to
  27. provide any services, by way of maintenance, update, or otherwise.
  28.  
  29. 5. In conjunction with products arising from the use of this material,
  30. there shall be no use of the name of the Massachusetts Institute of
  31. Technology nor of any adaptation thereof in any advertising,
  32. promotional, or sales literature without prior written consent from
  33. MIT in each case. */
  34.  
  35. #ifndef _BCHGCC_H_INCLUDED
  36.  
  37. #define _BCHGCC_H_INCLUDED
  38.  
  39. #include "oscond.h"
  40. #include "gccode.h"
  41.  
  42. #ifdef _BSD
  43. #  include <sys/file.h>
  44. #else
  45. #  ifndef F_GETFL
  46. #    include <fcntl.h>
  47. #  endif
  48. #endif
  49.  
  50. #ifndef DOS386
  51. #  include <sys/param.h>
  52. #else
  53. #  define IO_PAGE_SIZE        4096
  54. #endif
  55.  
  56. #ifndef BCH_START_CLOSURE_RELOCATION
  57. #  define BCH_START_CLOSURE_RELOCATION(scan) do { } while (0)
  58. #endif
  59.  
  60. #ifndef BCH_END_CLOSURE_RELOCATION
  61. #  define BCH_END_CLOSURE_RELOCATION(scan) do { } while (0)
  62. #endif
  63.  
  64. #ifndef BCH_EXTRACT_CLOSURE_ENTRY_ADDRESS
  65. #  define BCH_EXTRACT_CLOSURE_ENTRY_ADDRESS EXTRACT_CLOSURE_ENTRY_ADDRESS
  66. #endif
  67.  
  68. #ifndef BCH_STORE_CLOSURE_ENTRY_ADDRESS
  69. #  define BCH_STORE_CLOSURE_ENTRY_ADDRESS STORE_CLOSURE_ENTRY_ADDRESS
  70. #endif
  71.  
  72.  
  73. #ifndef BCH_START_OPERATOR_RELOCATION
  74. #  define BCH_START_OPERATOR_RELOCATION(scan) do { } while (0)
  75. #endif
  76.  
  77. #ifndef BCH_END_OPERATOR_RELOCATION
  78. #  define BCH_END_OPERATOR_RELOCATION(scan) do { } while (0)
  79. #endif
  80.  
  81. #ifndef BCH_EXTRACT_OPERATOR_LINKAGE_ADDRESS
  82. #  define BCH_EXTRACT_OPERATOR_LINKAGE_ADDRESS EXTRACT_OPERATOR_LINKAGE_ADDRESS
  83. #endif
  84.  
  85. #ifndef BCH_STORE_OPERATOR_LINKAGE_ADDRESS
  86. #  define BCH_STORE_OPERATOR_LINKAGE_ADDRESS STORE_OPERATOR_LINKAGE_ADDRESS
  87. #endif
  88.  
  89.  
  90. extern char * EXFUN (error_name, (int));
  91.  
  92. extern int EXFUN (retrying_file_operation,
  93.           (/* no prototype because (CONST char *) != (char *) */
  94.            int EXFUN((*), ()),
  95.            int, char *, long, long, char *, char *, long *,
  96.            int EXFUN((*), (char *, char *))));
  97.  
  98. extern int EXFUN (io_error_retry_p, (char *, char *));
  99. extern int EXFUN (io_error_always_abort, (char *, char *));
  100.  
  101. #define GC_FILE_FLAGS        (O_RDWR | O_CREAT) /* O_SYNCIO removed */
  102. #define GC_FILE_MASK        0644    /* Everyone reads, owner writes */
  103.  
  104. /* IO_PAGE_SIZE must be a power of 2! */
  105.  
  106. #ifndef IO_PAGE_SIZE
  107. #  ifdef DEV_BSIZE
  108. #    define IO_PAGE_SIZE DEV_BSIZE
  109. #  else
  110. #    define IO_PAGE_SIZE 8192
  111. #  endif
  112. #endif
  113.  
  114. #define ALIGN_DOWN_TO_IO_PAGE(addr)                    \
  115.   (((unsigned long) (addr)) & (~(IO_PAGE_SIZE - 1)))
  116.  
  117. #define ALIGN_UP_TO_IO_PAGE(addr)                    \
  118.   (ALIGN_DOWN_TO_IO_PAGE (((unsigned long) (addr)) + (IO_PAGE_SIZE - 1)))
  119.  
  120. #define ALIGNED_TO_IO_PAGE_P(addr)                    \
  121.   (((unsigned long) (addr)) == (ALIGN_DOWN_TO_IO_PAGE (addr)))
  122.  
  123. extern long
  124.   gc_file_end_position,
  125.   gc_file_current_position,
  126.   gc_file_start_position;
  127.  
  128. extern unsigned long
  129.   gc_buffer_size,
  130.   gc_buffer_bytes,
  131.   gc_buffer_shift,
  132.   gc_buffer_mask,
  133.   gc_buffer_byte_shift;
  134.  
  135. extern char
  136.   gc_death_message_buffer[];
  137.  
  138. extern SCHEME_OBJECT
  139.   * scan_buffer_top,
  140.   * scan_buffer_bottom,
  141.   * free_buffer_top,
  142.   * free_buffer_bottom,
  143.   * weak_pair_stack_ptr,
  144.   * weak_pair_stack_limit,
  145.   * virtual_scan_pointer;
  146.  
  147. extern SCHEME_OBJECT
  148.   * EXFUN (GCLoop, (SCHEME_OBJECT *, SCHEME_OBJECT **, SCHEME_OBJECT **)),
  149.   * EXFUN (dump_and_reload_scan_buffer, (long, Boolean *)),
  150.   * EXFUN (dump_and_reset_free_buffer, (long, Boolean *)),
  151.   * EXFUN (dump_free_directly, (SCHEME_OBJECT *, long, Boolean *)),
  152.   * EXFUN (initialize_free_buffer, (void)),
  153.   * EXFUN (initialize_scan_buffer, (SCHEME_OBJECT *)),
  154.   EXFUN (read_newspace_address, (SCHEME_OBJECT *));
  155.  
  156. extern void
  157.   EXFUN (GC, (int)),
  158.   EXFUN (end_transport, (Boolean *)),
  159.   EXFUN (final_reload, (SCHEME_OBJECT *, unsigned long, char *)),
  160.   EXFUN (extend_scan_buffer, (char *, SCHEME_OBJECT *)),
  161.   EXFUN (gc_death, (long, char *, SCHEME_OBJECT *, SCHEME_OBJECT *)),
  162.   EXFUN (restore_gc_file, (void)),
  163.   EXFUN (initialize_weak_pair_transport, (SCHEME_OBJECT *));
  164.  
  165. extern char
  166.   * EXFUN (end_scan_buffer_extension, (char *));
  167.  
  168. extern int
  169.   EXFUN (swap_gc_file, (int));
  170.  
  171. /* Some utility macros */
  172.  
  173. /* These work even when scan/addr point to constant space
  174.    because initialize_free_buffer (in bchmmg.c) cleverly initializes
  175.    scan_buffer_bottom, scan_buffer_top, and virtual_scan_pointer
  176.    so that the operations below do the right thing.
  177.  
  178.    These depend on (scan) and (addr) always pointing past the current
  179.    Scan pointer!
  180.  */
  181.  
  182. #define SCAN_POINTER_TO_NEWSPACE_ADDRESS(scan)                \
  183.   (((char *) virtual_scan_pointer)                    \
  184.    + (((char *) (scan)) - ((char *) scan_buffer_bottom)))
  185.       
  186. #define READ_NEWSPACE_ADDRESS(loc, addr) do                \
  187. {                                    \
  188.   SCHEME_OBJECT * _addr, * _scaddr;                    \
  189.                                     \
  190.   _addr = (addr);                            \
  191.   _scaddr = (scan_buffer_bottom + ((_addr) - virtual_scan_pointer));    \
  192.                                     \
  193.   if ((_scaddr >= scan_buffer_bottom) && (_scaddr < scan_buffer_top))    \
  194.     (loc) = (* _scaddr);                        \
  195.   else if ((_addr >= Constant_Space) && (_addr < Free_Constant))    \
  196.     (loc) = (* _addr);                            \
  197.   else                                    \
  198.     (loc) = (read_newspace_address (_addr));                \
  199. } while (0)
  200.  
  201. #define copy_weak_pair()                        \
  202. {                                    \
  203.   SCHEME_OBJECT weak_car;                        \
  204.   long car_type;                            \
  205.                                     \
  206.   weak_car = (*Old++);                            \
  207.   car_type = (OBJECT_TYPE (weak_car));                    \
  208.   if ((car_type == TC_NULL)                        \
  209.       || ((OBJECT_ADDRESS (weak_car)) >= Low_Constant))            \
  210.   {                                    \
  211.     *To++ = weak_car;                            \
  212.     *To++ = (*Old);                            \
  213.   }                                    \
  214.   else if (weak_pair_stack_ptr > weak_pair_stack_limit)            \
  215.   {                                    \
  216.     *--weak_pair_stack_ptr = ((SCHEME_OBJECT) To_Address);        \
  217.     *--weak_pair_stack_ptr = weak_car;                    \
  218.     *To++ = SHARP_F;                            \
  219.     *To++ = (*Old);                            \
  220.   }                                    \
  221.   else                                    \
  222.   {                                    \
  223.     *To++ = (OBJECT_NEW_TYPE (TC_NULL, weak_car));            \
  224.     *To++ = *Old;                            \
  225.     *Old = (OBJECT_NEW_TYPE (car_type, Weak_Chain));            \
  226.     Weak_Chain = Temp;                            \
  227.   }                                    \
  228. }
  229.  
  230. #define copy_cell()                            \
  231. {                                    \
  232.   *To++ = *Old;                                \
  233. }
  234.  
  235. #define copy_pair()                            \
  236. {                                    \
  237.   *To++ = *Old++;                            \
  238.   *To++ = *Old;                                \
  239. }
  240.  
  241. #define copy_triple()                            \
  242. {                                    \
  243.   *To++ = *Old++;                            \
  244.   *To++ = *Old++;                            \
  245.   *To++ = *Old;                                \
  246. }
  247.  
  248. #define copy_quadruple()                        \
  249. {                                    \
  250.   *To++ = *Old++;                            \
  251.   *To++ = *Old++;                            \
  252.   *To++ = *Old++;                            \
  253.   *To++ = *Old;                                \
  254. }
  255.  
  256. /* Transporting vectors is done in 3 parts:
  257.    - Finish filling the current free buffer, dump it, and get a new one.
  258.    - Dump the middle of the vector directly by bufferfulls.
  259.    - Copy the end of the vector to the new buffer.
  260.    The last piece of code is the only one executed when the vector does
  261.    not overflow the current buffer.
  262. */
  263.  
  264. #define copy_vector(success)                        \
  265. {                                    \
  266.   SCHEME_OBJECT * Saved_Scan = Scan;                    \
  267.   unsigned long real_length = (1 + (OBJECT_DATUM (*Old)));        \
  268.                                     \
  269.   To_Address += real_length;                        \
  270.   Scan = (To + real_length);                        \
  271.   if (Scan >= free_buffer_top)                        \
  272.   {                                    \
  273.     unsigned long overflow;                        \
  274.                                     \
  275.     overflow = (Scan - free_buffer_top);                \
  276.     while (To != free_buffer_top)                    \
  277.       *To++ = *Old++;                            \
  278.     To = (dump_and_reset_free_buffer (0, success));            \
  279.     real_length = (overflow >> gc_buffer_shift);            \
  280.     if (real_length > 0)                        \
  281.       To = dump_free_directly (Old, real_length, success);        \
  282.     Old += (real_length << gc_buffer_shift);                \
  283.     Scan = To + (overflow & gc_buffer_mask);                \
  284.   }                                    \
  285.   while (To != Scan)                            \
  286.     *To++ = *Old++;                            \
  287.   Scan = Saved_Scan;                            \
  288. }
  289.  
  290. /* Utility macros. */
  291.  
  292. #define relocate_normal_setup()                        \
  293. {                                    \
  294.   Old = (OBJECT_ADDRESS (Temp));                    \
  295.   if (Old >= Low_Constant)                        \
  296.     continue;                                \
  297.   if ((OBJECT_TYPE (*Old)) == TC_BROKEN_HEART)                \
  298.   {                                    \
  299.     *Scan = (MAKE_OBJECT_FROM_OBJECTS (Temp, *Old));            \
  300.     continue;                                \
  301.   }                                    \
  302.   New_Address = (MAKE_BROKEN_HEART (To_Address));            \
  303. }
  304.  
  305. #define relocate_normal_transport(copy_code, length)            \
  306. {                                    \
  307.   copy_code;                                \
  308.   To_Address += (length);                        \
  309.   if (To >= free_buffer_top)                        \
  310.     To = (dump_and_reset_free_buffer ((To - free_buffer_top), NULL));    \
  311. }
  312.  
  313. #define relocate_normal_end()                        \
  314. {                                    \
  315.   *(OBJECT_ADDRESS (Temp)) = New_Address;                \
  316.   *Scan = (MAKE_OBJECT_FROM_OBJECTS (Temp, New_Address));        \
  317.   continue;                                \
  318. }
  319.  
  320. #define relocate_normal_pointer(copy_code, length)            \
  321. {                                    \
  322.   relocate_normal_setup ();                        \
  323.   relocate_normal_transport (copy_code, length);            \
  324.   relocate_normal_end ();                        \
  325. }
  326.  
  327. #ifdef FLOATING_ALIGNMENT
  328.  
  329. #define FLOAT_ALIGN_FREE(free,free_ptr)                    \
  330. do {                                    \
  331.   while ((((long) ((free) + 1)) & FLOATING_ALIGNMENT) != 0)        \
  332.   {                                    \
  333.     free += 1;                                \
  334.     *free_ptr++ = (MAKE_OBJECT (TC_MANIFEST_NM_VECTOR, 0));        \
  335.   }                                    \
  336. } while (0)
  337.  
  338. #define relocate_flonum_setup()                        \
  339. {                                    \
  340.   relocate_normal_setup ();                        \
  341.   FLOAT_ALIGN_FREE (To_Address, To);                    \
  342.   New_Address = (MAKE_BROKEN_HEART (To_Address));            \
  343. }
  344.  
  345. #else /* FLOATING_ALIGNMENT */
  346.  
  347. #define FLOAT_ALIGN_FREE(free,free_ptr)                    \
  348. do {                                    \
  349. } while (0)
  350.  
  351. #define relocate_flonum_setup()    relocate_normal_setup()
  352.  
  353. #endif /* FLOATING_ALIGNMENT */
  354.  
  355. /* Typeless objects (implicit types). */
  356.  
  357. #define relocate_typeless_setup()                    \
  358. {                                    \
  359.   Old = ((SCHEME_OBJECT *) Temp);                    \
  360.   if (Old >= Low_Constant)                        \
  361.     continue;                                \
  362.   if ((OBJECT_TYPE (*Old)) == TC_BROKEN_HEART)                \
  363.   {                                    \
  364.     *Scan = ((SCHEME_OBJECT) (OBJECT_ADDRESS (*Old)));            \
  365.     continue;                                \
  366.   }                                    \
  367.   New_Address = ((SCHEME_OBJECT) To_Address);                \
  368. }
  369.  
  370. #define relocate_typeless_transport(copy_code, length)            \
  371. {                                    \
  372.   relocate_normal_transport (copy_code, length);            \
  373. }
  374.  
  375. #define relocate_typeless_end()                        \
  376. {                                    \
  377.   (* ((SCHEME_OBJECT *) Temp)) = (MAKE_BROKEN_HEART (New_Address));    \
  378.   *Scan = New_Address;                            \
  379.   continue;                                \
  380. }
  381.  
  382. #define relocate_typeless_pointer(copy_code, length)            \
  383. {                                    \
  384.   relocate_typeless_setup ();                        \
  385.   relocate_typeless_transport (copy_code, length);            \
  386.   relocate_typeless_end ();                        \
  387. }
  388.  
  389. /* The following macro uses do-while to trap the use of continue.
  390.    On certain machines, the operator/closure need to be updated
  391.    since the only addressing mode is pc-relative and the object
  392.    containing the reference may not be at the same address as it was
  393.    last time.
  394.    In addition, we may be in the middle of a scan-buffer extension,
  395.    which we need to finish.
  396.  */
  397.  
  398. #define relocate_compiled_entry(in_gc_p) do                \
  399. {                                    \
  400.   Old = (OBJECT_ADDRESS (Temp));                    \
  401.   if (Old >= Low_Constant)                        \
  402.     continue;                                \
  403.   Compiled_BH (in_gc_p, continue);                    \
  404.   {                                    \
  405.     SCHEME_OBJECT *Saved_Old = Old;                    \
  406.                                     \
  407.     New_Address = (MAKE_BROKEN_HEART (To_Address));            \
  408.     copy_vector (NULL);                            \
  409.     * Saved_Old = New_Address;                        \
  410.     Temp = (RELOCATE_COMPILED (Temp,                    \
  411.                    (OBJECT_ADDRESS (New_Address)),        \
  412.                    Saved_Old));                \
  413.     continue;                                \
  414.   }                                    \
  415. } while (0)
  416.  
  417. #define relocate_linked_operator(in_gc_p)                \
  418. {                                    \
  419.   Scan = ((SCHEME_OBJECT *) (word_ptr));                \
  420.   BCH_EXTRACT_OPERATOR_LINKAGE_ADDRESS (Temp, Scan);            \
  421.   relocate_compiled_entry (in_gc_p);                    \
  422.   BCH_STORE_OPERATOR_LINKAGE_ADDRESS (Temp, Scan);            \
  423. }
  424.  
  425. #define relocate_manifest_closure(in_gc_p)                \
  426. {                                    \
  427.   Scan = ((SCHEME_OBJECT *) (word_ptr));                \
  428.   BCH_EXTRACT_CLOSURE_ENTRY_ADDRESS (Temp, Scan);            \
  429.   relocate_compiled_entry (in_gc_p);                    \
  430.   BCH_STORE_CLOSURE_ENTRY_ADDRESS (Temp, Scan);                \
  431. }
  432.  
  433. #endif /* _BCHGCC_H_INCLUDED */
  434.